package com.nb.service.impl;

import com.nb.constant.JwtClaimsConstant;
import com.nb.constant.MessageConstant;
import com.nb.dto.user.LoginDTO;
import com.nb.dto.user.RegisterDTO;
import com.nb.entity.User;
import com.nb.exception.BusinessException;
import com.nb.mapper.UserMapper;
import com.nb.properties.JwtProperties;
import com.nb.service.UserService;
import com.nb.utils.JwtUtil;
import com.nb.utils.UrlUtil;
import com.nb.vo.user.UserLoginVO;
import com.nb.entity.UserInfo;
import com.nb.mapper.PatientMapper; // 导入 PatientMapper
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; // 导入 Transactional
import org.springframework.util.DigestUtils;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;

/**
 * 用户服务实现类
 */
@Service
@Slf4j
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private PatientMapper patientMapper; // 注入 PatientMapper

    @Autowired
    private JwtProperties jwtProperties;


    /**
     * 用户注册
     *
     * @param registerDTO 注册信息
     * @return 用户信息
     */
    @Override
    @Transactional // 添加事务注解
    public User register(RegisterDTO registerDTO) {

        // 1. 检查两次密码是否一致
//        if (!registerDTO.getPassword().equals(registerDTO.getConfirmPassword())) {
//            throw new BusinessException(MessageConstant.PASSWORD_NOT_MATCH);
//        }

        // 2. 检查账号是否已存在
        User existUser = userMapper.getByAccountAndRole(registerDTO.getAccount(), registerDTO.getRole());
        if (existUser != null) {
            throw new BusinessException(MessageConstant.ACCOUNT_EXISTED);
        }

        // 3. 密码加密
        String encryptedPassword = DigestUtils.md5DigestAsHex(registerDTO.getPassword().getBytes());

        // 4. 构建用户对象
        User user = User.builder()
                .account(registerDTO.getAccount())
                .password(encryptedPassword)
                .role("患者")
                .status(1) // 默认为启用状态
                .name("新用户")
                .createTime(LocalDateTime.now())
                .updateTime(LocalDateTime.now())
                .build();

        // 5. 保存用户
        userMapper.insert(user);
        log.info("新用户插入成功，ID: {}", user.getId());

// 6. 插入到患者信息表 patient_info
        Map<String, Object> patientParams = new HashMap<>();
        patientParams.put("userId", user.getId());
        patientParams.put("name", user.getName()); // 使用用户表中的姓名作为默认患者姓名
        patientParams.put("phone", "无"); // 确保这个字段被传递到 SQL 语句中
        patientParams.put("createTime", LocalDateTime.now());
        patientParams.put("updateTime", LocalDateTime.now());
        patientMapper.insertPatientInfo(patientParams);
        log.info("为用户 ID: {} 创建了关联的患者信息记录", user.getId());
        // 返回用户信息，不包含密码
        user.setPassword(null);
        return user;
    }

    /**
     * 用户登录
     *
     * @param loginDTO 登录信息
     * @return 登录结果(token + 用户信息)
     */
    @Override
    public UserLoginVO login(LoginDTO loginDTO) {
        String secretKey = jwtProperties.getAdminSecretKey();
        log.info("secretKey: {}", secretKey);

        long ttl = jwtProperties.getAdminTtl();
        // 1. 根据账号及角色查询用户
        User user = userMapper.getByAccountAndRole(loginDTO.getAccount(), loginDTO.getRole());
        if (user == null) {
            throw new BusinessException(MessageConstant.ACCOUNT_NOT_FOUND);
        }

        // 2. 密码比对
        String encryptedPassword = DigestUtils.md5DigestAsHex(loginDTO.getPassword().getBytes());
        if (!encryptedPassword.equals(user.getPassword())) {
            throw new BusinessException(MessageConstant.PASSWORD_ERROR);
        }

        // 3. 检查账号状态
        if (user.getStatus() == 0) {
            throw new BusinessException(MessageConstant.ACCOUNT_LOCKED);
        }

        // 4. 生成JWT令牌
        Map<String, Object> claims = new HashMap<>();
        claims.put(JwtClaimsConstant.USER_ID, user.getId());
        claims.put(JwtClaimsConstant.USER_NAME, user.getName());
        claims.put(JwtClaimsConstant.USER_ROLE, user.getRole());
        String token = JwtUtil.createJWT(
                jwtProperties.getAdminSecretKey(),
                jwtProperties.getAdminTtl(),
                claims);


        // 5. 构建返回结果
        // 处理头像URL
        String avatarUrl = UrlUtil.buildFullUrl(user.getAvatar());
        
        UserInfo userInfo = UserInfo.builder()
                .id(user.getId())
                .account(user.getAccount())
                .name(user.getName())
                .role(user.getRole())
                .avatar(avatarUrl)
                .build();

        return UserLoginVO.builder()
                .token(token)
                .userInfo(userInfo)
                .build();
    }
}